﻿#include "dataStructAlg.h"

Line::Line(Point sP_, Point eP_, Point mP_) { //圆弧
	Line line;
	line.Pt1 = this->Pt1 = sP_;
	line.Pt2 = this->Pt2 = eP_;
	line.arcP = this->arcP = mP_;
	line.State = this->State = 1;
	getCenterP(line);
}

Line::Line(Point sP_, Point eP_) { //线段
	this->Pt1 = sP_;
	this->Pt2 = eP_;
	this->arcP = eP_;
	this->State = 0;
}


Line::Line(Point circlePoint, double circleRadius) {   // 圆
	this->circleCenter = circlePoint;
	this->Radius = circleRadius;
	this->State = 2;
}

double Line::cross(Point a, Point b)const {    //叉乘
	return a.x * b.y - a.y * b.x;
}


Point Line::rotate(Point vec, double angle) {
	double rad = angle * PI / 180.0;
	Point rotate_vec = Point(vec.x * cos(rad) - vec.y * sin(rad), vec.y * cos(rad) + vec.x * sin(rad));
	return rotate_vec;
}

double Line::norm(Point a) {    //向量的模
	return sqrt(a.x * a.x + a.y * a.y);
}

Point Line::getVector() const{    //向量
	return (this->Pt2 - this->Pt1);
}


//计算圆弧时的圆心
void Line::getCenterP(Line line) {
	//cout << "@@@@@@@@@@@@@@@@@@@@@@@  Enter to get arc's circlePoint: " << endl;
	Point sP_, eP_, mP_;
	Point meVec, seVec, mcVec, vec1, meVecVertical;
	Point meVecnorm, seVecnorm, mcVecnorm, ceVecnorm;
	Point midSE, midME;
	Point circleCentralPoint;  //y圆心

	auto getCrossingPoint = [&](Point Vec1, Point p1, Point Vec2, Point p2) {
		Point P1P2 = p2 - p1;
		double t = cross(P1P2, Vec2) / cross(Vec1, Vec2);
		return p1 + Vec1 * t;
		};
	auto PointLinearDist = [](Point point1, Point point2) {
		double distance;
		distance = sqrt((point1.x - point2.x) * (point1.x - point2.x) + (point1.y - point2.y) * (point1.y - point2.y));
		return distance;
		};
	//初始化
	sP_ = line.Pt1;
	eP_ = line.Pt2;
	mP_ = line.arcP;
	midSE = Point((sP_.x + eP_.x) / 2, (sP_.y + eP_.y) / 2);
	midME = Point((mP_.x + eP_.x) / 2, (mP_.y + eP_.y) / 2);

	vec1 = mP_ - midSE; //判断用
	meVec = eP_ - mP_;
	seVec = eP_ - sP_;
	mcVec = rotate(seVec, -90);  //法向量
	meVecVertical = rotate(meVec, -90);

	circleCentralPoint = getCrossingPoint(meVecVertical, midME, mcVec, midSE);

	this->circleCenter = circleCentralPoint;
	this->Radius = PointLinearDist(circleCentralPoint, sP_);
}
Point Line::getCrossingPoint(Line& otherLine) const {
	Point P1P2 = otherLine.Pt2 - this->Pt2;
	Point Vec1 = this->Pt2 - this->Pt1;
	Point Vec2 = otherLine.Pt2 - otherLine.Pt1;
	double t = cross(P1P2, Vec2) / cross(Vec1, Vec2);
	return this->Pt2 + Vec1 * t;
}

double Line::getLength() const{
	Point p = this->Pt2 - this->Pt1;
	return sqrt(p.x * p.x + p.y * p.y);
}

bool Line::operator==(Line line1) const
{
	if (State != line1.State) {
		return false;
	}
	else if ((State == line1.State) && (State == 0)) {  //线段
		return ((Pt1 == line1.Pt1 && Pt2 == line1.Pt2) || (Pt2 == line1.Pt1 && Pt1 == line1.Pt2));
	}
	else if ((State == line1.State) && (State == 1)) {  //圆弧
		return (((Pt1 == line1.Pt1 && Pt2 == line1.Pt2) || (Pt2 == line1.Pt1 && Pt1 == line1.Pt2)) && arcP == line1.arcP);
	}
	else {
		return false;
	}
}
//bool Line::operator<(Line other) {
//
//}

